--- 模块功能：串口功能测试(非TASK版，串口帧有自定义的结构)
-- @author openLuat
-- @module uart.testUart
-- @license MIT
-- @copyright openLuat
-- @release 2018.03.27

module(...,package.seeall)

require"utils"
require"pm"



--[[
功能定义：

		 uart按照帧结构接收外围设备的输入，收到正确的指令后，改变车检器的对应状态

		 数据解析：
				  数据长度为19个字节，第15个字节为车磁id，第17个字节为车的状态
]]


--串口ID,1对应uart1
--如果要修改为uart2，把UART_ID赋值为2即可
local UART_ID = 2
--串口读到的数据缓冲区
local rdbuf = ""




--车检器上是否有车,有车:1;无车或者车已离开:0
u2_device1 =0
u2_device2 =0
u2_device3 =0
u2_device4 =0
u2_device5 =0





--[[
函数名：judgment
功能  ：判断车检器的状态
参数  ：
		car_id		：地磁ID
		car_value	：带有车辆状态的值 0x31有车    0x30无车
返回值：无
]]
local function judgment(car_id,car_value)
	print("car_value:",car_value,"car_id:",car_id)
	if car_id == 51 then     --0x33
		if car_value == 49 then   --0x31
			u2_device1=1
		elseif car_value == 48 then		--0x30
			u2_device1=0
		end
	elseif car_id == 52 then	--0x34
		if car_value == 49 then
			u2_device2=1
		elseif car_value == 48 then		
			u2_device2=0
		end
	elseif car_id == 53 then	--0x35
		if car_value == 49 then   
			u2_device3=1
		elseif car_value == 48 then		
			u2_device3=0
		end
	elseif car_id == 54 then	--0x36
		if car_value == 49 then   
			u2_device4=1
		elseif car_value == 48 then		
			u2_device4=0
		end
	elseif car_id == 55 then	--0x37		
		if car_value == 49 then  
			u2_device5=1
		elseif car_value == 48 then		
			u2_device5=0
		end
	end
	print("u2_device1:",u2_device1,"u2_device2:",u2_device2,"u2_device3:",u2_device3,"u2_device4:",u2_device4,"u2_device5:",u2_device5)
end


--[[
函数名：parse
功能  ：按照帧结构解析处理一条完整的帧数据
参数  ：
        data：所有未处理的数据
返回值：第一个返回值是一条完整帧报文的处理结果，第二个返回值是未处理的数据
]]
local function parse(data)
    if not data then return end 
	local u2_head = string.find(data,"*")
	if u2_head then
		local u2_tail = string.find(data,utils.string.fromHex("0D0A"))
		if not u2_tail then return false,data end
		judgment(string.byte(data,u2_tail-3),string.byte(data,u2_tail-1))
	end
	return true,nil
end

--[[
函数名：proc
功能  ：处理从串口读到的数据
参数  ：
        data：当前一次从串口读到的数据
返回值：无
]]
local function proc(data)
    if not data or string.len(data) == 0 then return end
    --追加到缓冲区
    rdbuf = rdbuf..data    
    
    local result,unproc
    unproc = rdbuf
    --根据帧结构循环解析未处理过的数据
    while true do
        result,unproc = parse(unproc)
        if not unproc or unproc == "" or not result then
            break
        end
    end

    rdbuf = unproc or ""
end



--[[
函数名：read
功能  ：读取串口接收到的数据
参数  ：无
返回值：无
]]
local function read()
    local data = ""
    --底层core中，串口收到数据时：
    --如果接收缓冲区为空，则会以中断方式通知Lua脚本收到了新数据；
    --如果接收缓冲器不为空，则不会通知Lua脚本
    --所以Lua脚本中收到中断读串口数据时，每次都要把接收缓冲区中的数据全部读出，这样才能保证底层core中的新数据中断上来，此read函数中的while语句中就保证了这一点
    while true do        
        data = uart.read(UART_ID,"*l")
        if not data or string.len(data) == 0 then break end
        proc(data)
    end
end



--[[
函数名：write
功能  ：通过串口发送数据
参数  ：
        s：要发送的数据
返回值：无
]]
function write(s)
    --log.info("testUart.write",s)
    uart.write(UART_ID,s)
end


local function writeOk()
    log.info("testUart.writeOk")
end



--保持系统处于唤醒状态，此处只是为了测试需要，所以此模块没有地方调用pm.sleep("testUart")休眠，不会进入低功耗休眠状态
--在开发“要求功耗低”的项目时，一定要想办法保证pm.wake("testUart")后，在不需要串口时调用pm.sleep("testUart")
pm.wake("uart2")
--注册串口的数据接收函数，串口收到数据后，会以中断方式，调用read接口读取数据
uart.on(UART_ID,"receive",read)
--注册串口的数据发送通知函数
uart.on(UART_ID,"sent",writeOk)

--配置并且打开串口
uart.setup(UART_ID,9600,8,uart.PAR_NONE,uart.STOP_1)
--如果需要打开“串口发送数据完成后，通过异步消息通知”的功能，则使用下面的这行setup，注释掉上面的一行setup
--uart.setup(UART_ID,115200,8,uart.PAR_NONE,uart.STOP_1,nil,1)
